package org.mozhu.mboot.core.web;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.AntPathMatcher;
import org.springframework.util.CollectionUtils;
import org.springframework.util.PathMatcher;

import javax.servlet.http.HttpServletRequest;
import java.util.Set;

public class HttpServletRequestSkipper {

	private final Logger logger = LoggerFactory.getLogger(HttpServletRequestSkipper.class);

	private final PathMatcher pathMatcher = new AntPathMatcher();

	private Set<String> exclusions;
	private Set<String> inclusions;

	public HttpServletRequestSkipper(Set<String> exclusions) {
		this.exclusions = exclusions;
	}

	public HttpServletRequestSkipper(Set<String> exclusions, Set<String> inclusions) {
		this.exclusions = exclusions;
		this.inclusions = inclusions;
	}

	public boolean needSkip(HttpServletRequest request) {
		return needSkip(request.getServletPath());
	}

	// 黑名单先判断，白名单后判断，若黑名单和白名单均有，则视为黑名单
	private boolean needSkip(String servletPath) {
		return inExclusionList(servletPath) || !inInclusionList(servletPath);
	}

	private boolean inExclusionList(String sevletPath) {
		// 若未指定黑名单，返回false，即默认所有请求会执行delegate.doFilter方法
		if (CollectionUtils.isEmpty(exclusions)) {
			return false;
		}
		for (String exclusion : exclusions) {
			if (pathMatcher.match(exclusion, sevletPath)) {
				logger.debug("SevletPath [{}] matchs Exclusion [{}], SevletPath [{}]", sevletPath, exclusion);
				return true;
			}
		}
		return false;
	}

	private boolean inInclusionList(String sevletPath) {
		// 若未指定白名单，返回true，即默认所有请求都会执行delegate.doFilter方法
		if (CollectionUtils.isEmpty(inclusions)) {
			logger.debug("SevletPath [{}] allways matchs empty Inclusions", sevletPath);
			return true;
		}
		for (String inclusion : inclusions) {
			if (pathMatcher.match(inclusion, sevletPath)) {
				logger.debug("SevletPath [{}] matchs Inclusion [{}], SevletPath [{}]", sevletPath, inclusion);
				return true;
			}
		}
		return false;
	}
}
